home *** CD-ROM | disk | FTP | other *** search
/ SunSoft Catalyst CDWARE 1996 May to August / Catalyst CDWARE 1996 May to August.iso / .products / JavaWorld / javaworld / cgi-bin / jw-search.cgi < prev    next >
Text File  |  1996-02-14  |  6KB  |  253 lines

  1. #!/usr/local/bin/perl
  2. # jw-search - search engine for JavaWorld.
  3. #
  4. # $docroot is set to the absolute pathname of the JavaWorld
  5. # content directory. this varies from mirror site to mirror site and
  6. # must be change appropriately.
  7. #
  8. # the search string comes in as the variable 'searchstring'.
  9. # case-sensitivity is determined by the value of 'casesensitive' (it
  10. # is either 'yes' or 'no').
  11.  
  12. $docroot="/netra2/ns-home/javaworld";
  13. $mailprog="/usr/lib/sendmail";
  14. $bcc="jw-search\@javaworld.com"; # recipient of failsafe copy
  15. $bccname="JW search";
  16. $bccsubject="jwsearch";
  17. $debug="/var/tmp/jw-search.$$";
  18.  
  19. read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
  20.  
  21. &sendhome;
  22.  
  23. # split the name-value pairs
  24. @pairs = split(/&/,$buffer);
  25.  
  26. foreach $pair (@pairs)
  27. {
  28.    ($name,$value) = split(/=/,$pair);
  29.    $value =~ tr/+/ /;
  30.    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
  31.  
  32.    # Stop people from using subshells to execute commands
  33.    $value =~ s/~!/ ~!/g; 
  34.  
  35.    $form{$name} = $value;
  36. }
  37.  
  38. $origsearchstring = $form{'searchstring'};
  39. $form{'searchstring'} =~ s#/#\\/#g;
  40.  
  41. if ($form{'casesensitive'} eq "no") {
  42.    $casestr = "case insensitive";
  43. }
  44. else {
  45.    $casestr = "case sensitive";
  46. }
  47.  
  48. &init_variables;
  49.  
  50. if ($form{'searchstring'} !~ /[\w]/) {
  51.    print "$emptysearchstring";
  52.    exit(0);
  53. }
  54.  
  55. &crawl("$docroot");
  56.  
  57. if (!defined(%hits)) {
  58.    print "$nomatchesfound";
  59.    exit(0);
  60. }
  61.  
  62. &dedupe_hits;
  63.  
  64. $matchnum = keys(%hits);
  65. $matchstr = $matchnum == 1 ? "match" : "matches";
  66.  
  67. $hits = "Content-TYPE:   text/html\n\n<HTML>
  68. <HEAD><TITLE>SunWorld Online Search Response</TITLE></HEAD>
  69. <BODY>
  70. <P>
  71. <H2>Thank you for searching <EM>SunWorld Online</EM>. We appreciate 
  72. your patronage. Send any questions, comments, or suggestions to 
  73. <A HREF=\"/javaworld/cgi-bin/jw-mailto.cgi?webmaster\@javaworld.com\">webmaster\@javaworld.com</A>.
  74. <P>
  75. Search string ($casestr): <EM>$origsearchstring</EM>
  76. <P>
  77. $matchnum $matchstr found
  78. <P>
  79. Results (ranked by number of occurences of search string in document):</H2>
  80. <P>
  81. ";
  82.  
  83. foreach $i (sort(by_hits_value keys(%hits))) {
  84.    $j = $i;
  85.    eval("\$j =~ s#^$docroot#/javaworld#");
  86.    $hits = $hits."<BR><STRONG>$hits{$i}</STRONG> <A HREF=\"$j\">$j</A>\n";
  87. }
  88.  
  89. $hits = $hits."<P>\n</BODY>\n</HTML>\n";
  90.  
  91. print "$hits";
  92.  
  93. exit(0);
  94.  
  95. sub search {
  96.    local($file) = $_[0];
  97.    local($options,$line) = ("","");
  98.  
  99.    $options = "i" if $form{'casesensitive'} eq "no";
  100.  
  101.    open(FILE,"<$file") || return;
  102.  
  103.    eval("while (<FILE>) {
  104.       \$_ =~ s/<[^<>]+>//g;
  105.       if (\$_ =~ /$form{'searchstring'}/$options) {
  106.          \$hits{\$file}++;
  107.       }
  108.    }");
  109.  
  110.    close(FILE);
  111. }
  112.  
  113. sub crawl {
  114.    local($i,$file);
  115.  
  116.    if (-d $_[0]) {
  117.       opendir(DIR,$_[0]) || return;
  118.       local(@files) = readdir(DIR);
  119.       closedir(DIR);
  120.  
  121.       foreach $i (@files) {
  122.  
  123.          next if $i eq "." || $i eq "..";
  124.  
  125.          ($file = "$_[0]/$i") =~ s;[/]{2,};/;g;
  126.  
  127.          if (-d $file) {
  128.             &crawl($file);
  129.          }
  130.          elsif (-f $file) {
  131.             &search($file) if $file =~ /\.html$/;
  132.          }
  133.       }
  134.    }
  135.    elsif (-f $_[0]) {
  136.       &search($_[0]) if $_[0] =~ /\.html$/;
  137.    }
  138. }
  139.  
  140. sub dedupe_hits {
  141.    local(%links,%inodes,%nhits,$i,$j,$dev);
  142.  
  143.    undef(%links);
  144.    undef(%inodes);
  145.    undef(%nhits);
  146.  
  147.    foreach $i (keys %hits) {
  148.       ($dev,$inodes{$i}) = stat($i);
  149.       $links{$inodes{$i}} = $i if $i !~ /index\.html/;
  150.    }
  151.  
  152.    foreach $i (keys %links) {
  153.       $nhits{$links{$i}} = $hits{$links{$i}};
  154.    }
  155.  
  156.    %hits = %nhits;
  157. }
  158.  
  159. sub by_number {
  160.    if ($a < $b) {
  161.       -1;
  162.    }
  163.    elsif ($a == $b) {
  164.       0;
  165.    }
  166.    elsif ($a > $b) {
  167.       1;
  168.    }
  169. }
  170.  
  171. sub by_hits_value {
  172.    if ($hits{$a} < $hits{$b}) {
  173.       1;
  174.    }
  175.    elsif ($hits{$a} == $hits{$b}) {
  176.       0;
  177.    }
  178.    elsif ($hits{$a} > $hits{$b}) {
  179.       -1;
  180.    }
  181. }
  182.  
  183. sub init_variables {
  184.    $emptysearchstring = "Content-TYPE:   text/html
  185.  
  186. <HTML>
  187. <HEAD><TITLE>SunWorld Online Search Response</TITLE></HEAD>
  188. <BODY>
  189. <P>
  190. <H2>
  191. Thank you for attempting to search <EM>SunWorld Online</EM>. We 
  192. appreciate your patronage. However, an empty search string was
  193. detected. If you really want to search <EM>SunWorld Online's</EM>
  194. archives, hit your browser\'s \"back\" button and try again.
  195. <P>
  196. Send any questions, comments, or suggestions to
  197. <A HREF=\"/cgi-bin/jw-mailto.cgi?webmaster\@javaworld.com\">webmaster\@javaworld.com</A>.
  198. </H2> 
  199. </BODY>
  200. </HTML>
  201. ";
  202.  
  203.    $nomatchesfound = "Content-TYPE:   text/html
  204.  
  205. <HTML>
  206. <HEAD><TITLE>SunWorld Online Search Response</TITLE></HEAD>
  207. <BODY>
  208. <P>
  209. <H2>
  210. Alas, no matches to your search string ($casestr):
  211. <P>
  212. <EM>$origsearchstring</EM>
  213. <P>
  214. were found.
  215. <P>
  216. Thank you for searching <EM>SunWorld Online</EM>. We appreciate your patronage.
  217. Send any questions, comments, or suggestions to
  218. <A HREF=\"/cgi-bin/jw-mailto.cgi?webmaster\@javaworld.com\">webmaster\@javaworld.com</A>.
  219. </H2> 
  220. </BODY>
  221. </HTML>
  222. ";
  223. }
  224.  
  225. sub sendhome {
  226.    $date=`date`; chop($date);
  227.    open(MAIL,"|$mailprog $bcc") || return;
  228.    print MAIL "From: $bcc ($bccname)\n";
  229.    print MAIL "To: $bcc\n";
  230.    print MAIL "Subject: $bccsubject\n\n";
  231.    print MAIL "BEGIN RECORD $date\n";
  232.    print MAIL "CONTENT_LENGTH=$ENV{'CONTENT_LENGTH'}\n";
  233.    print MAIL "CONTENT_TYPE=$ENV{'CONTENT_TYPE'}\n";
  234.    print MAIL "DOCUMENT_ROOT=$ENV{'DOCUMENT_ROOT'}\n";
  235.    print MAIL "GATEWAY_INTERFACE=$ENV{'GATEWAY_INTERFACE'}\n";
  236.    print MAIL "HTTP_REFERER=$ENV{'HTTP_REFERER'}\n";
  237.    print MAIL "HTTP_USER_AGENT=$ENV{'HTTP_USER_AGENT'}\n";
  238.    print MAIL "QUERY_STRING=$ENV{'QUERY_STRING'}\n";
  239.    print MAIL "REMOTE_ADDR=$ENV{'REMOTE_ADDR'}\n";
  240.    print MAIL "REMOTE_HOST=$ENV{'REMOTE_HOST'}\n";
  241.    print MAIL "REQUEST_METHOD=$ENV{'REQUEST_METHOD'}\n";
  242.    print MAIL "SCRIPT_NAME=$ENV{'SCRIPT_NAME'}\n";
  243.    print MAIL "SERVER_NAME=$ENV{'SERVER_NAME'}\n";
  244.    print MAIL "SERVER_PORT=$ENV{'SERVER_PORT'}\n";
  245.    print MAIL "SERVER_PROTOCOL=$ENV{'SERVER_PROTOCOL'}\n";
  246.    print MAIL "SERVER_SOFTWARE=$ENV{'SERVER_SOFTWARE'}\n";
  247.    print MAIL "ARGV=@ARGV\n";
  248.    print MAIL "STDINDATA=$buffer\n";
  249.    print MAIL "END RECORD $date\n";
  250.    close(MAIL);
  251. }
  252.  
  253.